package com.info33.platform.system.service.impl;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.info33.platform.system.vo.SysAnnouncementVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.info33.platform.system.dao.SysAnnouncementAuthDao;
import com.info33.platform.system.dao.SysAnnouncementDao;
import com.info33.platform.system.entity.SysAnnouncement;
import com.info33.platform.system.entity.SysAnnouncementAuth;
import com.info33.platform.system.service.SysAnnouncementAuthService;
import com.info33.platform.system.service.SysAnnouncementService;
import com.info33.platform.common.mvc.vo.Result;
import com.info33.platform.system.dao.SysTenantUserDao;
import com.info33.platform.system.dao.SysUserDao;
import com.info33.platform.system.entity.SysTenantUser;
import com.info33.platform.system.entity.SysUser;
import com.info33.platform.system.util.enums.UserTypeEnum;

@Service("SysAnnouncementService")
public class SysAnnouncementServiceImpl extends ServiceImpl<SysAnnouncementDao, SysAnnouncement>
		implements SysAnnouncementService {
	@Autowired
	SysUserDao sysUserDao;
	@Autowired
	SysTenantUserDao sysTenantUserDao;
	@Autowired
	SysAnnouncementDao sysAnnouncementDao;
	@Autowired
	SysAnnouncementAuthService sysAnnouncementAuthService;
	@Autowired
	SysAnnouncementAuthDao sysAnnouncementAuthDao;

	@SuppressWarnings("all")
	@Override
	public SysAnnouncement get(Long id, Long tenantId) throws Exception {
		SysAnnouncement sysAnnouncement = sysAnnouncementDao.selectById(id);
		Map<String, Object> userInfo = sysUserDao.queryUserListById(sysAnnouncement.getCreateBy(), tenantId);
		String createName = userInfo.get("trueName").toString();
		sysAnnouncement.setCreateName(createName);
		Map<String, Object> authMap = JSONObject.parseObject(sysAnnouncement.getAuthGroup(), Map.class);
		// 转换权限组别中的信息
		if (authMap.size() > 0) {
			if (!(null == authMap.get("userIds") || "".equals(authMap.get("userIds")))) {

				List<String> stringArr = (List<String>) authMap.get("userIds");
				List<String> finalUser = new ArrayList<String>();
				for (String userId : stringArr) {
					SysTenantUser sysTenantUser = sysTenantUserDao.selectById(userId);
					SysUser sysUser = sysUserDao.selectById(sysTenantUser.getUserId());
					if (sysUser != null) {
						finalUser.add(sysUser.getTrueName());
					}
				}
				authMap.put("userNames", finalUser);
			}
			if (!(null == authMap.get("roleIds") || "".equals(authMap.get("roleIds")))) {
				List<String> stringArr = (List<String>) authMap.get("roleIds");
				List<String> finalRole = new ArrayList<String>();
				for (String roleId : stringArr) {
					if (sysUserDao.queryRoleListById(roleId, tenantId) != null) {
						finalRole.add(sysUserDao.queryRoleListById(roleId, tenantId).get("roleName").toString());
					}
				}
				authMap.put("roleNames", finalRole);
			}
			if (!(null == authMap.get("groupIds") || "".equals(authMap.get("groupIds")))) {
				List<String> stringArr = (List<String>) authMap.get("groupIds");
				List<String> finalGroup = new ArrayList<String>();
				for (String groupId : stringArr) {
					if (sysUserDao.queryDeptListByIds(groupId, tenantId) != null) {
						finalGroup.add(sysUserDao.queryDeptListByIds(groupId, tenantId).get("deptName").toString());
					}
				}
				authMap.put("groupIdNames", finalGroup);
			}
			if (!(null == authMap.get("groupRoleIds") || "".equals(authMap.get("groupRoleIds")))) {
				List<Map<String, Object>> stringArr = (List<Map<String, Object>>) authMap.get("groupRoleIds");
				List<Map<String, Object>> finalGroupRole = new ArrayList<Map<String, Object>>();
				for (Map<String, Object> groupRoleMap : stringArr) {
					List<String> roleNameList = new ArrayList<>();
					List<String> groupNameList = new ArrayList<>();
					List<String> roleIdList = JSONObject.parseObject(groupRoleMap.get("roleId").toString(), List.class);
					List<String> groupIdList = JSONObject.parseObject(groupRoleMap.get("groupId").toString(),
							List.class);
					Map<String, Object> map = new HashMap<>();
					map.put("roleName", "");
					map.put("groupName", "");
					if (roleIdList.size() > 0) {
						for (String roleId : roleIdList) {
							if (sysUserDao.queryRoleListById(roleId, tenantId) != null) {
								roleNameList
										.add(sysUserDao.queryRoleListById(roleId, tenantId).get("roleName").toString());
							}
						}
						map.put("roleName", roleNameList);
					}
					if (groupIdList.size() > 0) {
						for (String groupId : groupIdList) {
							if (sysUserDao.queryDeptListByIds(groupId, tenantId) != null) {
								groupNameList.add(
										sysUserDao.queryDeptListByIds(groupId, tenantId).get("deptName").toString());
							}
						}
						map.put("groupName", groupNameList);
					}
					finalGroupRole.add(map);
				}

				authMap.put("groupRoleNames", finalGroupRole);
			}
			String authMapString = JSON.toJSONString(authMap);
			sysAnnouncement.setAuthGroup(authMapString);
		}
		return sysAnnouncement;
	}

	@SuppressWarnings("all")
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Result<SysAnnouncement> add(SysAnnouncement sysAnnouncement) throws Exception {
		int num = sysAnnouncementDao.insert(sysAnnouncement);
		boolean flag = false;
		Map<String, Object> authGroupMap = JSONObject.parseObject(sysAnnouncement.getAuthGroup(), Map.class);
		// 选择全体人员，,用特殊标志标记
		if ("true".equals(sysAnnouncement.getAuthAll())) {
			SysAnnouncementAuth sysAnnouncementAuth = new SysAnnouncementAuth();
			sysAnnouncementAuth.setTenantId(sysAnnouncement.getTenantId());
			sysAnnouncementAuth.setMainId(sysAnnouncement.getId().toString());
			sysAnnouncementAuth.setUserId("all");
			flag = sysAnnouncementAuthService.save(sysAnnouncementAuth);
		}

		// 未选择全体人员
		if ("false".equals(sysAnnouncement.getAuthAll())) {
			if (authGroupMap.size() > 0) {
				// 选择人员
				if (!(null == authGroupMap.get("userIds") || "".equals(authGroupMap.get("userIds")))) {
					List<String> userIds = (List<String>) authGroupMap.get("userIds");
					for (String userId : userIds) {
						SysAnnouncementAuth sysAnnouncementAuth = new SysAnnouncementAuth();
						sysAnnouncementAuth.setTenantId(sysAnnouncement.getTenantId());
						sysAnnouncementAuth.setMainId(sysAnnouncement.getId().toString());
						sysAnnouncementAuth.setUserId(userId);
						flag = sysAnnouncementAuthService.save(sysAnnouncementAuth);
					}
				}
				// 选择岗位
				if (!(null == authGroupMap.get("roleIds") || "".equals(authGroupMap.get("roleIds")))) {
					List<String> roleIds = (List<String>) authGroupMap.get("roleIds");
					for (String roleId : roleIds) {
						SysAnnouncementAuth sysAnnouncementAuth = new SysAnnouncementAuth();
						sysAnnouncementAuth.setTenantId(sysAnnouncement.getTenantId());
						sysAnnouncementAuth.setMainId(sysAnnouncement.getId().toString());
						sysAnnouncementAuth.setRoleId(roleId);
						flag = sysAnnouncementAuthService.save(sysAnnouncementAuth);
					}
				}
				// 选择部门
				if (!(null == authGroupMap.get("groupIds") || "".equals(authGroupMap.get("groupIds")))) {
					List<String> groupIds = (List<String>) authGroupMap.get("groupIds");
					for (String groupId : groupIds) {
						SysAnnouncementAuth sysAnnouncementAuth = new SysAnnouncementAuth();
						sysAnnouncementAuth.setTenantId(sysAnnouncement.getTenantId());
						sysAnnouncementAuth.setMainId(sysAnnouncement.getId().toString());
						sysAnnouncementAuth.setGroupId(groupId);
						flag = sysAnnouncementAuthService.save(sysAnnouncementAuth);
					}
				}

				// 选择特定部门岗位
				if (!(null == authGroupMap.get("groupRoleIds") || "".equals(authGroupMap.get("groupRoleIds")))) {
					List<Map<String, Object>> groupRoleIds = (List<Map<String, Object>>) authGroupMap
							.get("groupRoleIds");
					for (Map<String, Object> groupRoleMap : groupRoleIds) {
						List<String> roleIdList = JSONObject.parseObject(groupRoleMap.get("roleId").toString(),
								List.class);
						List<String> groupIdList = JSONObject.parseObject(groupRoleMap.get("groupId").toString(),
								List.class);
						if (groupIdList.size() > 0) {
							for (String groupId : groupIdList) {
								if (roleIdList.size() > 0) {
									for (String roleId : roleIdList) {
										SysAnnouncementAuth sysAnnouncementAuth = new SysAnnouncementAuth();
										sysAnnouncementAuth.setTenantId(sysAnnouncement.getTenantId());
										sysAnnouncementAuth.setMainId(sysAnnouncement.getId().toString());
										sysAnnouncementAuth.setGroupId(groupId);
										sysAnnouncementAuth.setRoleId(roleId);
										flag = sysAnnouncementAuthService.save(sysAnnouncementAuth);
									}
								}
							}
						}
					}
				}
			}
		}
		//// 操作存在异常抛出，进行事务回滚
		if (num < 0) {
			throw new Exception("系统异常！");
		}
		if (flag == false) {
			throw new Exception("系统异常！");
		}

		return Result.ok(sysAnnouncement);
	}

	@SuppressWarnings("all")
	@Override
	public IPage getHisListByAuth(Long curUserId, Long tenantUserId, Long tenantId, UserTypeEnum userType,
			SysAnnouncement sysAnnouncement, int pageNum, int pageSize) {
		Page page = new Page(pageNum, pageSize);
		// 公告类型
		String type = sysAnnouncement.getType();
		Map<String, Object> map = new HashMap<>();
		String curId = curUserId.toString();
//		IPage<SysAnnouncement> sysAnnouncements = sysAnnouncementDao.selectPage(page,
//				new QueryWrapper<SysAnnouncement>(sysAnnouncement).eq("tenant_id", tenantId).orderByAsc("start_time")
//						.orderByDesc("create_date"));
		IPage<SysAnnouncement> sysAnnouncements = sysAnnouncementDao.getAnnouncementPage(page,tenantId);
		if ("ADMIN".equals(userType.ADMIN.name())) {
			return sysAnnouncements;
		}
		Map<String, Object> userMap = sysUserDao.queryUserListById(Long.parseLong(curId), tenantId);
		List<Map<String, Object>> mainIdList = sysAnnouncementDao.getMainIdList(userMap);
		String str = "";
		if (mainIdList.size() > 0) {
			for (Map<String, Object> map2 : mainIdList) {
				str += map2.get("id").toString() + ",";
			}
			String userStr = "SELECT a.*,c.new_name as files FROM sys_announcement a left join doc_file b  on a.file_id=b.id left join doc_file_detail c  on c.file_id=b.id WHERE a.id IN("
					+ str.substring(0, str.length() - 1) + ") union All ";
			// 当前用户自己发起的公告
			String sqlStr = userStr
					+ " SELECT a.*,c.new_name as files FROM sys_announcement a left join doc_file b  on a.file_id=b.id left join doc_file_detail c  on c.file_id=b.id  WHERE a.current_id="
					+ tenantUserId + " group by id";
			map.put("sqlStr", sqlStr);
			// map.put("type", sysAnnouncement.getType());
			IPage<SysAnnouncement> finalList = sysAnnouncementDao.getHistoryList(page, map);
			return finalList;
		} else {// 默认可见当前用户自己发起的公告
			map.put("curId", tenantUserId);
			// map.put("type", sysAnnouncement.getType());
			IPage<SysAnnouncement> defaultList = sysAnnouncementDao.getDefaultHisList(page, map);
			return defaultList;
		}
	}

	@SuppressWarnings("all")
	@Override
	public IPage getListByAuth(Long curUserId, Long tenantUserId, Long tenantId, UserTypeEnum userType,
			SysAnnouncement sysAnnouncement, int pageNum, int pageSize) throws ParseException {
		String curId = curUserId.toString();
		// 公告类型
		// String type= sysAnnouncement.getType();
		Page page = new Page(pageNum, pageSize);
		Date dates = new Date();
		Map<String, Object> map = new HashMap<>();
//		IPage<SysAnnouncement> sysAnnouncements = sysAnnouncementDao.selectPage(page,
//				new QueryWrapper<SysAnnouncement>(sysAnnouncement).eq("tenant_id", tenantId).lt("start_time", dates)
//						.gt("end_time", dates).orderByAsc("start_time").orderByDesc("create_date"));
		IPage<SysAnnouncement> sysAnnouncements = sysAnnouncementDao.getAnnouncementPage(page,tenantId);
		if ("ADMIN".equals(userType.ADMIN.name())) {
			return sysAnnouncements;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String date = sdf.format(dates);
		Map<String, Object> userMap = sysUserDao.queryUserListById(Long.parseLong(curId), tenantId);
		List<Map<String, Object>> mainIdList = sysAnnouncementDao.getMainIdList(userMap);
		String str = "";
		if (mainIdList.size() > 0) {
			for (Map<String, Object> map2 : mainIdList) {
				str += map2.get("id").toString() + ",";
			}
			String userStr = "SELECT a.*,c.new_name as files FROM sys_announcement a left join doc_file b  on a.file_id=b.id left join doc_file_detail c  on c.file_id=b.id WHERE a.id IN("
					+ str.substring(0, str.length() - 1) + ") and start_time <\"" + date + "\" and end_time >\"" + date
					+ "\" union All ";
			// 当前用户自己发起的公告
			String sqlStr = userStr
					+ "SELECT a.*,c.new_name as files FROM sys_announcement a left join doc_file b  on a.file_id=b.id left join doc_file_detail c  on c.file_id=b.id WHERE  a.current_id="
					+ tenantUserId + " and start_time <\"" + date + "\" and end_time >\"" + date + "\"";
			map.put("sqlStr", sqlStr);
			// map.put("type", sysAnnouncement.getType());
			IPage<SysAnnouncement> finalList = sysAnnouncementDao.getHistoryList(page, map);
			return finalList;
		} else {// 默认可见当前用户自己发起的公告
			map.put("curId", tenantUserId);
			map.put("date", date);
			// map.put("type", sysAnnouncement.getType());
			IPage<SysAnnouncement> defaultList = sysAnnouncementDao.getDefaultList(page, map);
			return defaultList;
		}
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public int remove(Long id) throws Exception {

		int num = sysAnnouncementDao.deleteById(id);
		QueryWrapper<SysAnnouncementAuth> sysAnnouncementAuthWrapper = new QueryWrapper<>();
		num = sysAnnouncementAuthDao.delete(sysAnnouncementAuthWrapper.eq("main_id", id));
		// 操作存在异常抛出，进行事务回滚
		if (num < 0) {
			throw new Exception("系统异常！");
		}
		return num;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public Result<?> edit(SysAnnouncement sysAnnouncement) throws Exception {
		// boolean flag = false;
		int num = remove(sysAnnouncement.getId());
		if (num < 0) {
			throw new Exception("系统异常！");
		}
		sysAnnouncement.setId(null);
		return add(sysAnnouncement);
	}

	@Override
	public Result<?> getFiles(Long tenantId) {
		return Result.ok(20000, sysAnnouncementDao.getFiles(tenantId));
	}
}
